package com.kingtown.inventory.activity;

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;

import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.*;
import androidx.activity.EdgeToEdge;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;
import cn.hutool.core.util.StrUtil;
import com.google.gson.reflect.TypeToken;
import com.kingtown.inventory.MainApplication;
import com.kingtown.inventory.R;
import com.kingtown.inventory.Utils;
import com.kingtown.inventory.adapter.ClientAdapter;
import com.kingtown.inventory.adapter.FloorAdapter;
import com.kingtown.inventory.adapter.PositionAdapter;
import com.kingtown.inventory.domain.bo.AssetAddBo;
import com.kingtown.inventory.domain.dto.KiClient;
import com.kingtown.inventory.domain.dto.KiFloor;
import com.kingtown.inventory.domain.dto.KiPosition;
import com.kingtown.inventory.net.NetWorkManager;
import com.kingtown.inventory.utils.BarcodeUtil;
import com.rscja.barcode.BarcodeDecoder;
import com.rscja.deviceapi.entity.BarcodeEntity;
import com.rscja.team.qcom.deviceapi.T;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

public class AddActivity extends AppCompatActivity implements AdapterView.OnItemSelectedListener, View.OnClickListener {

    Context _this;
    TextView txtAssetEpc;
    EditText editAssetCode, editAssetName, editAssetAddress, editAssetRemark;
    Spinner spinnerClient, spinnerFloor, spinnerPosition;
    Button btnReset,btnBarcode, btnRfid, btnSubmit;

    MainApplication mApplication;

    List<KiClient> clients = new ArrayList<>();
    List<KiFloor> floors = new ArrayList<>();
    List<KiPosition> positions = new ArrayList<>();
    KiClient selectedClient;
    KiFloor selectedFloor;
    KiPosition selectedPosition;

    ClientAdapter clientAdapter;
    FloorAdapter floorAdapter;
    PositionAdapter positionAdapter;
    BarcodeUtil barcodeUtil;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_add);
        _this = this;
        mApplication = (MainApplication) getApplication();

        txtAssetEpc = findViewById(R.id.txt_add_epc);

        editAssetCode = findViewById(R.id.edit_add_asset_code);
        editAssetName = findViewById(R.id.edit_add_asset_name);
        editAssetAddress = findViewById(R.id.edit_add_address);
        editAssetRemark = findViewById(R.id.edit_add_remark);

        spinnerClient = findViewById(R.id.spinner_client);
        spinnerFloor = findViewById(R.id.spinner_floor);
        spinnerPosition = findViewById(R.id.spinner_position);

        clientAdapter = new ClientAdapter(_this, clients);
        floorAdapter = new FloorAdapter(_this, floors);
        positionAdapter = new PositionAdapter(_this, positions);

        spinnerClient.setAdapter(clientAdapter);
        spinnerFloor.setAdapter(floorAdapter);
        spinnerPosition.setAdapter(positionAdapter);
        spinnerClient.setOnItemSelectedListener(this);
        spinnerFloor.setOnItemSelectedListener(this);
        spinnerPosition.setOnItemSelectedListener(this);

        btnReset = findViewById(R.id.btn_add_reset);
        btnRfid = findViewById(R.id.btn_add_rfid);
        btnSubmit = findViewById(R.id.btn_add_submit);
        btnBarcode = findViewById(R.id.btn_add_barcode);
        btnReset.setOnClickListener(this);
        btnRfid.setOnClickListener(this);
        btnSubmit.setOnClickListener(this);
        btnBarcode.setOnClickListener(this);

        initClient();
        initBarcode();
    }

    @Override
    protected void onDestroy() {
        if(barcodeUtil!=null){
            barcodeUtil.close();
        }
        super.onDestroy();
    }

    private Handler myHandler = new Handler() {
        @Override
        //重写handleMessage方法,根据msg中what的值判断是否执行后续操作
        public void handleMessage(Message msg) {
            if (msg.what == 0) {
            }
        }
    };

    @Override
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.btn_add_submit -> {
                AssetAddBo bo = new AssetAddBo();
                bo.setAssetName(editAssetName.getText().toString());
                bo.setAssetCode(editAssetCode.getText().toString());
                bo.setAssetEpc(txtAssetEpc.getText().toString());
                bo.setClientId(selectedClient.getId());
                if (selectedFloor != null) {
                    bo.setFloorId(selectedFloor.getId());
                }
                if (selectedPosition != null) {
                    bo.setPositionId(selectedPosition.getId());
                }
                bo.setAddress(editAssetAddress.getText().toString());
                bo.setRemark(editAssetRemark.getText().toString());
                Log.i("submit", bo.toString());

                if (StrUtil.isBlank(bo.getAssetCode())) {
                    Toast.makeText(_this, "请扫描资产条形码", Toast.LENGTH_SHORT).show();
                    return;
                }
                if (StrUtil.isBlank(bo.getAssetEpc()) || bo.getAssetEpc().equals("扫描失败")) {
                    Toast.makeText(_this, "请扫描RFID芯片码", Toast.LENGTH_SHORT).show();
                    return;
                }
                executeSubmit(bo);
            }
            case R.id.btn_add_reset -> {
                resetAll();
            }
            case R.id.btn_add_rfid -> {
                String readEpc = mApplication.readTag();
                if (StrUtil.isBlank(readEpc)) {
                    Toast.makeText(_this, "扫描失败，请重新扫描", Toast.LENGTH_SHORT).show();
                    return;
                }
                txtAssetEpc.setText(readEpc);
            }
            case R.id.btn_add_barcode -> {
                if(barcodeUtil == null){
                    initBarcode();
                }
                barcodeUtil.start();
            }
        }
    }

    private void initBarcode(){
        barcodeUtil = new BarcodeUtil();
        barcodeUtil.init(_this);
        barcodeUtil.open(barcodeEntity -> {
            if (barcodeEntity.getResultCode() == BarcodeDecoder.DECODE_SUCCESS) {
                runOnUiThread(() -> {
                    editAssetCode.setText(barcodeEntity.getBarcodeData());
                });
            } else {
                Toast.makeText(_this, "条码或二维码扫描失败", Toast.LENGTH_SHORT).show();
            }
        });
    }

    @SuppressLint("CheckResult")
    private void initClient() {
        NetWorkManager.request()
                .listClient()
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(res -> {
                    if (res.isSuccess()) {
                        Log.i("res", res.toString());
                        String jsonString = mApplication.gson.toJson(res.getData());
                        clients.addAll(mApplication.gson.fromJson(jsonString, new TypeToken<List<KiClient>>() {
                        }.getType()));
                        clientAdapter.notifyDataSetChanged();
                    } else {
                        Toast.makeText(_this, "请求失败", Toast.LENGTH_SHORT).show();
                    }
                }, throwable -> {
                    Toast.makeText(_this, "请求失败：" + throwable + "！", Toast.LENGTH_SHORT).show();
                    Utils.hideProgressDialog();
                });
    }

    @SuppressLint("CheckResult")
    private void initFloor() {
        floors.clear();
        NetWorkManager.request()
                .listFloor(selectedClient.getId())
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(res -> {
                    if (res.isSuccess()) {
                        Log.i("res", res.toString());
                        String jsonString = mApplication.gson.toJson(res.getData());
                        KiFloor kiFloor = new KiFloor();
                        kiFloor.setFloor("选择全部");
                        floors.add(kiFloor);
                        floors.addAll(mApplication.gson.fromJson(jsonString, new TypeToken<List<KiFloor>>() {
                        }.getType()));
                        floorAdapter.notifyDataSetChanged();
                    } else {
                        Toast.makeText(_this, "请求失败", Toast.LENGTH_SHORT).show();
                    }
                }, throwable -> {
                    Toast.makeText(_this, "请求失败：" + throwable + "！", Toast.LENGTH_SHORT).show();
                    Utils.hideProgressDialog();
                });
    }

    @SuppressLint("CheckResult")
    private void initPosition() {
        positions.clear();
        NetWorkManager.request()
                .listPosition(selectedFloor.getId())
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(res -> {
                    if (res.isSuccess()) {
                        Log.i("res", res.toString());
                        String jsonString = mApplication.gson.toJson(res.getData());
                        KiPosition kiPosition = new KiPosition();
                        kiPosition.setPosition("选择全部");
                        positions.add(kiPosition);
                        positions.addAll(mApplication.gson.fromJson(jsonString, new TypeToken<List<KiPosition>>() {
                        }.getType()));
                        positionAdapter.notifyDataSetChanged();
                    } else {
                        Toast.makeText(_this, "请求失败", Toast.LENGTH_SHORT).show();
                    }
                }, throwable -> {
                    Toast.makeText(_this, "请求失败：" + throwable + "！", Toast.LENGTH_SHORT).show();
                    Utils.hideProgressDialog();
                });
    }

    @Override
    public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
        switch (adapterView.getId()) {
            case R.id.spinner_client -> {
                Toast.makeText(_this, "选择了" + adapterView.getItemAtPosition(i).toString(), Toast.LENGTH_SHORT).show();
                selectedClient = (KiClient) adapterView.getItemAtPosition(i);
                initFloor();
                positions.clear();
                positionAdapter.notifyDataSetChanged();
                selectedFloor = null;
                selectedPosition = null;
            }
            case R.id.spinner_floor -> {
                Toast.makeText(_this, "选择了" + adapterView.getItemAtPosition(i).toString(), Toast.LENGTH_SHORT).show();
                selectedFloor = (KiFloor) adapterView.getItemAtPosition(i);
                initPosition();
                selectedPosition = null;
            }
            case R.id.spinner_position -> {
                Toast.makeText(_this, "选择了" + adapterView.getItemAtPosition(i).toString(), Toast.LENGTH_SHORT).show();
                selectedPosition = (KiPosition) adapterView.getItemAtPosition(i);
            }
        }
    }

    @Override
    public void onNothingSelected(AdapterView<?> adapterView) {

    }

    private void reset() {
        txtAssetEpc.setText("");
        editAssetCode.setText("");
    }

    private void resetAll() {
        txtAssetEpc.setText("");
        editAssetCode.setText("");
        editAssetName.setText("");
        editAssetAddress.setText("");
        editAssetRemark.setText("");
        selectedPosition = null;
        selectedFloor = null;
        floors.clear();
        positions.clear();
        floorAdapter.notifyDataSetChanged();
        positionAdapter.notifyDataSetChanged();
    }

    @SuppressLint("CheckResult")
    private void executeSubmit(AssetAddBo bo) {
        NetWorkManager.request()
                .addAsset(bo)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(res -> {
                    if (res.isSuccess()) {
                        Log.i("res", res.toString());
                        Toast.makeText(_this, "新增成功", Toast.LENGTH_SHORT).show();
                        reset();
                    } else {
                        Toast.makeText(_this, "新增失败", Toast.LENGTH_SHORT).show();
                    }
                }, throwable -> {
                    Toast.makeText(_this, "新增失败：" + throwable + "！", Toast.LENGTH_SHORT).show();
                    Utils.hideProgressDialog();
                });
    }
}